package com.tengju.bff.interfaces.manage.crm.chief.facade;

import com.tengju.bff.interfaces.manage.crm.chief.assembler.ChiefClubAssembler;
import com.tengju.bff.interfaces.manage.crm.chief.vo.ChiefClubVO;
import com.tengju.bff.interfaces.manage.crm.chief.vo.GetChiefClubRelationForm;
import com.tengju.bff.interfaces.manage.crm.chief.vo.UpdateChiefClubRelationDTO;
import com.tengju.bff.interfaces.shared.ColumnVO;
import com.tengju.bff.interfaces.shared.PageResultVO;
import com.tengju.bff.interfaces.shared.TableVO;
import com.tengju.bff.interfaces.shared.servlet.ServletContextUtil;
import com.tengju.user.domain.model.chief.*;
import com.tengju.user.domain.model.club.Club;
import com.tengju.user.domain.model.club.ClubId;
import com.tengju.user.domain.model.club.ClubRepository;
import com.tengju.user.domain.model.user.SsoUserId;
import com.tengju.user.domain.model.user.Staff;
import com.tengju.user.domain.model.user.StaffInfo;
import com.tengju.user.domain.service.DepartmentExternalService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ChiefClubFacade {


    private final ClubRepository clubRepository;
    private final ChiefClubRepository chiefClubRepository;
    private final DepartmentExternalService departmentExternalService;

    public ChiefClubVO getChiefClub(ChiefId chiefId) {
        List<ClubId> clubIds = ServletContextUtil.getServletContext().getClubIds();
        List<Club> clubList = clubRepository.findByIds(clubIds);
        return ChiefClubAssembler.modelToVO(chiefId, clubList);
    }

    public Boolean updateChiefClubRelation(Staff staff, UpdateChiefClubRelationDTO updateChiefClubRelationDTO) {
        ChiefClubUpdateRelation chiefClubUpdateRelation = new ChiefClubUpdateRelation(
                new ChiefClubRelationId(updateChiefClubRelationDTO.getChiefClubRelationId()),
                new ChiefId(updateChiefClubRelationDTO.getChiefId()),
                new ClubId(updateChiefClubRelationDTO.getClubId()),
                staff.getName());
        chiefClubRepository.updateChiefClubRelation(chiefClubUpdateRelation);
        return true;
    }

    public TableVO queryChiefClubRelationByPage(GetChiefClubRelationForm getChiefClubRelationForm) {

        Integer pageSize = getChiefClubRelationForm.getPageSize();
        Integer pageIndex = getChiefClubRelationForm.getPageIndex();
        int offset = getChiefClubRelationForm.getOffset();

        TableVO table = new TableVO();
        List<ColumnVO> header = List.of(
                ColumnVO.of("clubName", "俱乐部名称", false),
                ColumnVO.of("realNameAndNickname", "负责人", false),
                ColumnVO.of("departmentFullName", "部门", false)
        );
        table.setHeader(header);

        int total = chiefClubRepository.count(
                Optional.ofNullable(getChiefClubRelationForm.getClubId()).map(ClubId::new).orElse(null),
                Optional.ofNullable(getChiefClubRelationForm.getChiefId()).map(ChiefId::new).orElse(null));


        List<ChiefClubRelation> chiefClubRelationList = new ArrayList<>();


        if (offset <= total) {
            chiefClubRelationList = chiefClubRepository.queryByClubIdAndChiefIdPage(
                    Optional.ofNullable(getChiefClubRelationForm.getClubId()).map(ClubId::new).orElse(null),
                    Optional.ofNullable(getChiefClubRelationForm.getChiefId()).map(ChiefId::new).orElse(null),
                    getChiefClubRelationForm.getOffset(),
                    getChiefClubRelationForm.getPageSize());
        }

        List<ChiefId> chiefIdList = chiefClubRelationList.stream().map(ChiefClubRelation::getChiefId).filter(Objects::nonNull).collect(Collectors.toList());
        List<StaffInfo> staffInfoList = departmentExternalService.getStaffInfos(chiefIdList.stream().map(v -> new SsoUserId(v.getValue())).collect(Collectors.toList()));

        Map<ChiefId, StaffInfo> map = staffInfoList.stream().collect(Collectors.toMap(v1 -> new ChiefId(v1.getSsoUserId().getValue()), v2 -> v2, (v1, v2) -> v1));

        List<Map<String, Object>> records = new ArrayList<>();

        for (ChiefClubRelation chiefClubRelation : chiefClubRelationList) {
            Map<String, Object> row = new HashMap<>();

            row.put("clubName", chiefClubRelation.getClubName());
            row.put("realNameAndNickname", getRealName(map, chiefClubRelation) + "(" + getNickname(map, chiefClubRelation) + ")");
            row.put("departmentFullName", getDepartmentFullName(map, chiefClubRelation));
            row.put("clubId", chiefClubRelation.getClubId().getValue());
            row.put("chiefId", chiefClubRelation.getChiefId().getValue());
            row.put("chiefClubRelationId", chiefClubRelation.getChiefClubRelationId().getValue());
            records.add(row);
        }
        table.setRecords(records);
        table.setPage(PageResultVO.of(pageIndex, pageSize, total));
        return table;
    }


    public String getRealName(Map<ChiefId, StaffInfo> map, ChiefClubRelation chiefClubRelation) {
        if (chiefClubRelation.getChiefId() == null || CollectionUtils.isEmpty(map)) {
            return "";
        }
        StaffInfo staffInfo = null;
        if ((staffInfo = map.get(chiefClubRelation.getChiefId())) == null) {
            return "";
        }
        return Optional.ofNullable(staffInfo.getRealName()).orElse("");
    }

    public String getNickname(Map<ChiefId, StaffInfo> map, ChiefClubRelation chiefClubRelation) {
        if (chiefClubRelation.getChiefId() == null || CollectionUtils.isEmpty(map)) {
            return "";
        }
        StaffInfo staffInfo = null;
        if ((staffInfo = map.get(chiefClubRelation.getChiefId())) == null) {
            return "";
        }
        return Optional.ofNullable(staffInfo.getNickname()).orElse("");
    }

    public String getDepartmentFullName(Map<ChiefId, StaffInfo> map, ChiefClubRelation chiefClubRelation) {
        if (chiefClubRelation.getChiefId() == null || CollectionUtils.isEmpty(map)) {
            return "";
        }
        StaffInfo staffInfo = null;
        if ((staffInfo = map.get(chiefClubRelation.getChiefId())) == null) {
            return "";
        }
        return Optional.ofNullable(staffInfo.getDepartmentFullName()).orElse("");
    }

}